/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Persistence;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.logging.Level;
import java.util.logging.Logger;
import servidorped.User;

/**
 *
 * @author Micosil
 */
public class UserMemory implements UserPersistence {

    private String path;
    List<User> userList = new ArrayList<>();
    ReadWriteLock lock = new ReentrantReadWriteLock(true);

    public UserMemory(String pathAlArchivoDeConfiguracion) {
        BufferedReader configReader = null;
        try {
            configReader = new BufferedReader(new FileReader(new File(pathAlArchivoDeConfiguracion)));
            configReader.readLine();
            this.path = configReader.readLine();
        } catch (IOException ex) {
            Logger.getGlobal().log(Level.WARNING, "Could not open Config.txt");
            path = "Users.txt";
        } finally{
            try {
                configReader.close();
            } catch (IOException ex) {
                Logger.getGlobal().log(Level.SEVERE, null, ex);
            }
        }

        BufferedReader userReader = null;
        try {
            userReader = new BufferedReader(new FileReader(new File(path)));
        } catch (FileNotFoundException ex) {
            Logger.getGlobal().log(Level.WARNING, "User-defining file not found. Users have not been loaded.", ex);
        }
        String oneLine;
        try {
            while ((oneLine = userReader.readLine()) != null) {
                StringTokenizer bynn = new StringTokenizer(oneLine, ",", false);
                String userName = bynn.nextToken();
                String realName = bynn.nextToken();
                String password = bynn.nextToken();
                String email = bynn.nextToken();
                String isAdmin = bynn.nextToken();
                User newUser = new User(userName, realName, password, email, isAdmin);
                userList.add(newUser);
            }
        } catch (IOException ex) {
            Logger.getGlobal().log(Level.WARNING, "User-defining file not found. Users have not been loaded.", ex);
        } catch (Exception ex) {
            Logger.getGlobal().log(Level.SEVERE, "Something blew up", ex);
        } finally {
            try {
                if (userReader != null)
                userReader.close();
            } catch (IOException ex) {
                Logger.getGlobal().log(Level.SEVERE, null, ex);
            }
        }
    }

    @Override
    public List<User> retrieveUsers() {
        return userList;
    }

    @Override
    public User getUserByName(String nameToBeFound) {
        for (User user : userList) {
            if (user.getUserName().equalsIgnoreCase(nameToBeFound)) {
                return user;
            }
        }
        return null;
    }

    public boolean identify(String userName, String password) {
        return getUserByName(userName).getPassword().equals(password);
    }

    @Override
    public boolean createUser(User user) {
        BufferedWriter iVillVrite = null;
        try {
            iVillVrite = new BufferedWriter(new FileWriter(new File(path)));
        } catch (IOException ex) {
            Logger.getGlobal().log(Level.SEVERE, "Could not open user storage file.", ex);
        }
        StringBuilder newUserData = new StringBuilder(user.getUserName());
        newUserData.append(",");
        newUserData.append(user.getRealName());
        newUserData.append(",");
        newUserData.append(user.getPassword());
        newUserData.append(",");
        newUserData.append(user.getEmailAdress());
        newUserData.append(",");
        newUserData.append("false");
        try {
            iVillVrite.append(newUserData);
        } catch (IOException ex) {
            Logger.getGlobal().log(Level.SEVERE, "Could not create new user " + user.getUserName(), ex);
            return false;
        } finally {
            try {
                if (iVillVrite != null)
                iVillVrite.close();
            } catch (IOException ex) {
                Logger.getGlobal().log(Level.SEVERE, null, ex);
            }
        }
        return true;

    }

    @Override
    public boolean deleteUser(String userName) {
        BufferedReader fileReader;   
        BufferedWriter fileWriter;
        lock.writeLock().lock();
        try {
            fileReader = new BufferedReader(new FileReader(new File(path)));
            
        } catch (FileNotFoundException ex) {
            Logger.getLogger(UserMemory.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        }
        try {
            fileWriter = new BufferedWriter(new FileWriter(new File("temp")));
        } catch (IOException ex) {
            try {
                fileReader.close();
            } catch (IOException ex1) {
                Logger.getLogger(UserMemory.class.getName()).log(Level.SEVERE, null, ex1);
            }
            Logger.getLogger(UserMemory.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        }
        String oneLine;
        try {
            while ((oneLine = fileReader.readLine()) != null){
               if (!oneLine.contains(userName))
                   fileWriter.write(oneLine);
            }
        } catch (IOException ex) {
            Logger.getLogger(UserMemory.class.getName()).log(Level.SEVERE, null, ex);
        }
        try {
            fileReader.close();
        } catch (IOException ex) {
            Logger.getLogger(UserMemory.class.getName()).log(Level.SEVERE, null, ex);
        }
        try {
            fileWriter.flush();
            fileWriter.close();
        } catch (IOException ex) {
            Logger.getLogger(UserMemory.class.getName()).log(Level.SEVERE, null, ex);
        }
        try {
            fileReader = new BufferedReader(new FileReader(new File("temp")));
        } catch (FileNotFoundException ex) {
            Logger.getLogger(UserMemory.class.getName()).log(Level.SEVERE, null, ex);
        }
        try {
            fileWriter = new BufferedWriter(new FileWriter(new File(path)));
        } catch (IOException ex) {
            try {
                fileReader.close();
            } catch (IOException ex1) {
                Logger.getLogger(UserMemory.class.getName()).log(Level.SEVERE, null, ex1);
            }
            Logger.getLogger(UserMemory.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        }
        try {
            while ((oneLine = fileReader.readLine()) != null){        
                       fileWriter.write(oneLine);
                }
        } catch (IOException ex) {
            Logger.getLogger(UserMemory.class.getName()).log(Level.SEVERE, null, ex);
        }
        try {
            fileWriter.flush();
            fileWriter.close();
        } catch (IOException ex) {
            Logger.getLogger(UserMemory.class.getName()).log(Level.SEVERE, null, ex);
        }
        try {
            fileReader.close();
        } catch (IOException ex) {
            Logger.getLogger(UserMemory.class.getName()).log(Level.SEVERE, null, ex);
        }        
        return true;
    }
    
}
